home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / gcl-1.000 / gcl-1 / gcl-1.0 / c / rel_rios.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-15  |  8.1 KB  |  285 lines

  1.  
  2. /* Copyright William Schelter. All rights reserved.  This file does
  3. the low level relocation which tends to be very system dependent.
  4. It is included by the file sfasl.c
  5. */
  6.  
  7. typedef int (*FUNC)();
  8. extern int akcltoc;
  9. extern int toc_start;
  10. static int current_toc;
  11. static int ptrgl_offset = 0;
  12. static int  ptrgl_text;
  13.  
  14. static int akcltoc_used=0;
  15.  
  16. /* This is an alternating list of addresses x1,y1,x2,y2,... where
  17.    relocation entries for changing value in address x1 shold be read as changing
  18.    it in y1 */
  19.  
  20. static  int  toc_addresses_to_relocate [10];
  21. static  int *next_toc_addresses_to_relocate = toc_addresses_to_relocate ;
  22. static int akcltoc_thisload;
  23. static int begun_relocate = 0;
  24.  
  25. static int set_rel_bits(address,bits,val)
  26.      char *address;
  27.      int val;
  28.      int bits;
  29. { bits += 1;
  30.  if ( bits <= 16)
  31.    {unsigned short  y = *(unsigned short *)address ;
  32.     y = y &  (~0 << bits) ;
  33.     y |= (val & ~(~0 << bits));
  34.     *(unsigned short *)address = val;
  35.   }
  36.   else
  37.    {unsigned int  y = *(unsigned int *)address ;
  38.     y = y &  (~0 << bits) ;
  39.     y |= (val & ~(~0 << bits));
  40.     *(unsigned int *)address = y;
  41.   }
  42. }
  43.  
  44. #ifdef AIX3
  45. struct syment *
  46. get_symbol(name,scnum,symbol_table,length)
  47.      char *name;
  48.      int scnum,length;
  49.      struct syment *symbol_table;
  50. { struct syment *end,*sym;
  51.  char tem[SYMNMLEN +1];
  52.   char *na;
  53.   end =symbol_table + length;
  54.   for(sym=symbol_table; sym < end; sym += (NUM_AUX(sym) +1))
  55.     {if ((sym)->n_scnum  == scnum)
  56.       { na=SYM_NAME(sym);
  57.     if (strcmp(name,na) == 0)
  58.       {return sym;}}}
  59.   return 0;}
  60. #endif /* aix3 */
  61.  
  62. /*
  63.  800b0000          l   r0,0x0(r11)  
  64.  90410014         st   r2,0x14(r1)  
  65.  7c0903a6      mtctr   r0           
  66.  804b0004          l   r2,0x4(r11)         
  67.  816b0008          l   r11,0x8(r11) 
  68.  4e800420       bctr                
  69. */
  70. int myptrgl[6] = {
  71.   0x800b0000, 0x90410014, 0x7c0903a6, 0x804b0004,
  72.   0x816b0008, 0x4e800420};
  73.  
  74. /* 7d8903a6      mtctr   r12 
  75.  4e800420       bctr
  76.  */
  77. static int jmp_r12[2] = { 0x7d8903a6, 0x4e800420};
  78.  
  79.   
  80. #define SYM_SMC(sym)  (((union auxent *)(sym+1))->x_csect.x_smclas)
  81. #define SYM_TOC_ADDR(sym)  (((union auxent *)(sym+1))->x_csect.x_parmhash)
  82. /* #define SYM_USED(sym)   (((union auxent *)(&sym[1]))->x_csect.x_snhash) */
  83. #define  TC_SYMBOL_P(sym) ((sym)->n_scnum == DATA_NSCN && NUM_AUX((sym)) && \
  84.                (SYM_SMC(sym) == XMC_TC0 ||  SYM_SMC(sym) == XMC_TC))
  85.                 
  86.  
  87.  
  88. int FIXtemp ;
  89. static int intcmp2(x,y)
  90.      int *x,*y;
  91. { return (*x - *y);
  92. }
  93.  
  94. #define  TOP6 (~0 << 26)
  95. #define  BR_IN_DATA_P(x) (((x) & TOP6) == (DBEGIN & TOP6))
  96.  
  97.  
  98. relocate()
  99. { struct syment *sym = &symbol_table[relocation_info.r_symndx];
  100.   char *where;
  101.   describe_sym(relocation_info.r_symndx);
  102.   where = the_start + relocation_info.r_vaddr;
  103.   dprintf (where has %x , *(int *)where);
  104.   dprintf(   at %x -->, where );
  105.  
  106.   if(begun_relocate == 0)
  107.     {int n =   next_toc_addresses_to_relocate - toc_addresses_to_relocate;
  108.        begun_relocate = 1;
  109.      FIXtemp = 0; /* dummy reference for export problem */
  110.      qsort((char *)toc_addresses_to_relocate, n/2 , 2*sizeof(int),  intcmp2);
  111.      next_toc_addresses_to_relocate
  112.        = toc_addresses_to_relocate;}
  113.  
  114.   switch(RELOC_RTYPE(relocation_info))
  115.     { int *q;
  116.  
  117.     case R_TOC:     /* TOC_ILodx */
  118.       set_rel_bits(where,RELOC_RLEN(relocation_info), sym->n_value -  toc_start) ;
  119.       break;
  120.     case R_POS:   /* Pos_Rel */
  121.  
  122.        if (where == *next_toc_addresses_to_relocate)
  123.      {where = next_toc_addresses_to_relocate [1];
  124.       next_toc_addresses_to_relocate +=  2;}
  125.  
  126.      if ( sym->n_scnum == N_UNDEF || TC_SYMBOL_P(sym))
  127.     set_rel_bits(where,RELOC_RLEN(relocation_info),  sym->n_value);
  128.      else
  129.        set_rel_bits(where,RELOC_RLEN(relocation_info), (*(int *)where)+ sym->n_value);
  130.  
  131.       break;
  132.     case R_BR:   /* Brn_Sel */
  133.  
  134.       {int link_bit = ((((int *)where)[0]) & 1);
  135.        if (((((int *)where)[0]) & TOP6 ) == 0x48000000)    /* bl or b relative */
  136.      {
  137.        if (((int *)where)[1] == 0x80410014) /* l   r2,0x14(r1) */
  138.          {int x = SYM_TOC_ADDR(sym);
  139.           if (x)
  140.         { ((int *)where)[0]  = 0x81820000 ; /*  l   r12,0x0(r2) */
  141.           set_rel_bits(where+2,15,x - toc_start);
  142.           (((int *)where)[1] = 0x48000000); /* b relative */
  143.           set_rel_bits(where+4, 0x19, ((int) jmp_r12) - ((int) where + 4 ));
  144.           ((int *)where)[1] |=  link_bit; /* link bit */
  145.           break;
  146.         }
  147.           else        /* must be ptrgl */
  148.         if  (BR_IN_DATA_P(sym->n_value))
  149.           {set_rel_bits(where, 0x19, sym->n_value - (int) where);
  150.            ((int *)where)[0] |=  link_bit; /* link bit */
  151.            break;}
  152.         }
  153.        else
  154.          if (BR_IN_DATA_P(sym->n_value))
  155.            {set_rel_bits(where, 0x19,  sym->n_value - (int) where);
  156.         ((int *)where)[0] |=  link_bit; /* link bit */
  157.         break;}}
  158.        else
  159.      FEerror("The type of Br_sel was new ",0,0);
  160.      }
  161.     default:
  162.       fprintf(stdout, "%d: unsupported relocation type.",
  163.           RELOC_RTYPE(relocation_info) );
  164.       FEerror("The relocation type was unknown",0,0);
  165.     }
  166.   dprintf( %x,*(int *)where);
  167.  
  168. }
  169.  
  170. fix_undef_toc_address(answ,sym,str)
  171.      char *str;
  172.      struct syment *sym;
  173.      struct node *answ;
  174.      /* undefined sym */
  175. { if (BR_IN_DATA_P(answ->address)) return;
  176.   if (answ->tc_offset == 0)
  177.     { answ->tc_offset = ( akcltoc + akcltoc_used - toc_start);
  178.       * ((int *)( akcltoc + akcltoc_used)) = answ->address;
  179.       akcltoc_used += sizeof(char *);
  180.     }
  181.  
  182.       if (NUM_AUX(sym))
  183.     SYM_TOC_ADDR(sym) =  (toc_start + answ->tc_offset);
  184.       else printf("symbol should have aux entry");
  185.   
  186.   return;
  187. }
  188.  
  189.       
  190.     
  191.     
  192.  
  193.  
  194. #ifdef DEBUG
  195. #undef describe_sym
  196. #define describe_sym(x) do{if(sfasldebug) describe_sym1(x);} while (0)
  197. describe_sym1(n)
  198. int n;
  199. {char *str;
  200.  char tem[9];
  201.  struct syment *sym;
  202.  sym= &symbol_table[n];
  203.  str= sym->n_zeroes == 0 ?
  204.    &my_string_table[sym->n_offset] :
  205.  (sym->n_name[SYMNMLEN -1] ?
  206.   /* MAKE IT NULL TERMINATED */
  207.   (strncpy(tem,sym->n_name,
  208.        SYMNMLEN),tem):
  209.   sym->n_name );
  210.  printf ("sym-index = %d table entry at %x",n,&symbol_table[n]);
  211.  printf("symbol is (%s):\nsymbol_table[n]._n._n_name %s\nsymbol_table[n]._n._n_n._n_zeroes %d\nsymbol_table[n]._n._n_n._n_offset %d\nsymbol_table[n]._n._n_nptr[0] %d\nsymbol_table[n]._n._n_nptr[n] %d\nsymbol_table[n].n_value %d\nsymbol_table[n].n_scnum %d nsymbol_table[n].n_type %d\nsymbol_table[n].n_sclass %d\nsymbol_table[n].n_numaux %d", str,
  212.     symbol_table[n]._n._n_name,
  213.     symbol_table[n]._n._n_n._n_zeroes ,
  214.     symbol_table[n]._n._n_n._n_offset ,
  215.     symbol_table[n]._n._n_nptr[0] ,
  216.     symbol_table[n]._n._n_nptr[1] ,
  217.     symbol_table[n].n_value ,
  218.     symbol_table[n].n_scnum ,
  219.     symbol_table[n].n_type ,
  220.     symbol_table[n].n_sclass ,
  221.     symbol_table[n].n_numaux );
  222. }
  223.  
  224. #endif 
  225.  
  226.  
  227.  
  228.  
  229. /* allocate toc space in the preallocated region starting at akcltoc.
  230.    If a symbol already has a toc entry, use that instead
  231.    */
  232.  
  233. setup_for_aix_load()
  234. { bzero(toc_addresses_to_relocate,sizeof(toc_addresses_to_relocate));
  235.   next_toc_addresses_to_relocate= toc_addresses_to_relocate;
  236.   akcltoc_thisload = akcltoc + akcltoc_used;
  237.   begun_relocate=0;
  238.  
  239. }
  240.  
  241. char *
  242. sym_name(sym)
  243.      struct syment *sym;
  244. {static char tem[SYMNMLEN +1];
  245.  char *name;
  246.  tem[SYMNMLEN] = '0';
  247.  name =  SYM_NAME(sym);
  248.  return name;}
  249.  
  250.          
  251.  
  252. allocate_toc(sym)
  253.  struct syment *sym;
  254.      /* sym is a symbol in the data section with an aux entry */ 
  255. { if (SYM_SMC(sym) == XMC_TC0)
  256.     { sym->n_value =  toc_start; return 1;}
  257.   if (SYM_SMC(sym) == XMC_TC)
  258.     {struct node *answ = find_sym(sym,0);
  259.      if (answ  && answ->tc_offset)
  260.        { sym->n_value = toc_start + answ->tc_offset;
  261.      return 1;}
  262.      {char *na = sym_name(sym);
  263. #ifdef SYM_USED      
  264.       if (TC_SYMBOL_P(sym) && SYM_USED(sym) == 0)
  265.     return 0;
  266. #endif
  267.       if (answ == 0 && *na  &&  *na != '_')
  268.     printf("(strange TC synbol %s[%d])",na,sym - symbol_table);}
  269.      {int old_value;
  270.       (*next_toc_addresses_to_relocate++) =  sym->n_value + start_address;
  271.       sym->n_value = akcltoc + akcltoc_used;
  272.       if (answ) answ->tc_offset = sym->n_value - toc_start;
  273.       (*next_toc_addresses_to_relocate++) = sym->n_value;
  274.       *((int *)(next_toc_addresses_to_relocate[-1])) =
  275.     *((int *)(next_toc_addresses_to_relocate[-2]));
  276.       akcltoc_used += sizeof(long int);
  277.       if (next_toc_addresses_to_relocate - toc_addresses_to_relocate
  278.       >= (sizeof(toc_addresses_to_relocate)/sizeof(int)))
  279.     FEerror("ran out");
  280.       if (akcltoc_used > 24000) FEerror("toc exhausted");
  281.       return 1;
  282.     }}
  283.   return 0;
  284. }
  285.